/*
Level.h 游戏主循环代码
*/

#ifndef LEVEL_H
#define LEVEL_H

#include <Player.h>
#include <Projectile.h>
#include <LevelAction.h>
#include <unordered_map>
#include <string>
#include <mutex>
#include <queue>

using namespace std;

/// @brief 游戏刻信息（每轮游戏主循环自增）
extern int gameTick;

class Level {
public:

    /// @brief 相应客户端Echo列表，主要用于延迟测定
    queue<string> echo;

    bool gameStarted = false;
    float leftTime = 300.0f;
    float roundTime = 300.0f;
    // 对局信息

    float mapWidth = 2500.0;
    float mapHeight = 2500.0;
    // 地图大小

    float youkaiDeployColdDown = 0.0f;
    float youkaiDeployColdDownMax = 15.0f;
    // NPC部署

    float itemDropPercentage = 0.6f;
    // 道具掉落概率

    bool autoStart = false;
    float currStartCountDown = 30.0f;
    float autoStartTime = 30.0f;
    int autoStartMinPlayerCount = 1;
    // 游戏自动开始设置

    int playerKnockDownScore = 1500;
    int youkaiKnockDownScore = 35;
    float damageScoreRatio = 1.0;
    int youkaiMissPenalize = 1000;
    // 得分行为信息

    string serverName;
    vector<string> serverInfo;
    // 服务器信息

    unordered_map<string, Player> players;
    unordered_map<string, Projectile> projectiles;
    unordered_map<string, Youkai> youkais;
    unordered_map<string, Item> items;
    // 全局实体列表

    /// @brief 更新关卡信息
    void update(const float rate, mutex& mtxLock, queue<LevelAction>& responseBuffer);
    /// @brief 重置所有玩家信息
    void resetAllPlayers(queue<LevelAction> &responseBuffer);
    /// @brief 重置关卡信息
    void resetLevelStatus(queue<LevelAction> &responseBuffer);
    /// @brief 同步对局全量信息
    void syncGlobalData(queue<LevelAction> &responseBuffer);
    /// @brief 创建新玩家
    void createNewPlayer(const LevelAction& interact);

private:
    void updateGameStatus(const float rate, queue<LevelAction>& responseBuffer);
    void updateGameAutoStart(const float rate, queue<LevelAction> &responseBuffer);
    void echoResponse(queue<LevelAction> &responseBuffer);
    void updatePlayerLimit(Player *targetPlayer, const float rate, queue<LevelAction> &responseBuffer);
    void updatePlayerOpenFire(Player* targetPlayer, const float rate, queue<LevelAction>& responseBuffer);
    // 游戏主循环相关

    void randomTurn(string bulletUuid, float turnRange);
    void linearFire(Player *targetPlayer, queue<LevelAction> &responseBuffer);
    Player *findNearestPlayer(string bulletUuid);
    Youkai *findNearestYoukai(string bulletUuid);
    void guidance(string bulletUuid, const float rate, float turnRange);
    void summonSubProjectile(string bulletUuid, const float rate, queue<LevelAction> &responseBuffer);
    void updateProjectileSpecial(Projectile *targetBullet, const float rate, queue<LevelAction> &responseBuffer);
    void updateProjectileDamage(Projectile *targetBullet, const float rate, queue<LevelAction> &responseBuffer);
    // 弹射物行为相关

    void updateItemCollection(Item *targetItem, const float rate, queue<LevelAction> &responseBuffer);
    // 道具行为相关

    void upadteYoukaiAction(Youkai *targetYoukai, const float rate, queue<LevelAction> &responseBuffer);
    void youkaiOpenFire(Youkai *targetYoukai, queue<LevelAction> &responseBuffer);
    void youkaiOpenAngleFire(Youkai *targetYoukai, float angle, queue<LevelAction> &responseBuffer, float speed);
    void updateYoukaiDeploy(const float rate, queue<LevelAction> &responseBuffer);
    Vector2 spawnRandomDirection();
    // NPC行为相关

    void createNewYoukai(string youkaiType, string uuid, Vector2 pos, queue<LevelAction> &responseBuffer);
    void createNewProjectile(string bulletType, string uuid, Vector2 pos, string ownerUuid,
        queue<LevelAction> &responseBuffer);
    void createNewItem(string uuid, Vector2 pos, queue<LevelAction> &responseBuffer);
    // 实体创建相关

    void delDeadProjectile(queue<LevelAction> &responseBuffer);
    void delDeadYoukai(queue<LevelAction> &responseBuffer);
    void delDeadItem(queue<LevelAction> &responseBuffer);
    // 删除实体相关

    void syncYoukaiData(Youkai *youkai, queue<LevelAction> &responseBuffer);
    void syncProjectileData(Projectile *projectile, queue<LevelAction> &responseBuffer);
    void syncItemData(Item *item, queue<LevelAction> &responseBuffer);
    // 信息同步相关
};

/// @brief 求方向的旋转角度
float vectorToAngle(float x, float y);

/// @brief 加入会话到传出缓存区
void pushToResponseBuffer(string actionName, vector<string> paramsList,
    queue<LevelAction>& responseBuffer);

/// @brief 向所有客户端广播消息
void sendGameLog(string content, queue<LevelAction>& responseBuffer);

#endif